﻿@using RuoVea.ExDto
@using RuoVea.OmiReports
@using RuoVea.OmiReports.Language
@using RuoVea.OmiReports.Attributes
@using RuoVea.OmiReports.Options
@{
    AppConfig Reports = ConfigManages.Config ?? new AppConfig();
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@Html.Raw(RuoVea.OmiReports.Language.i18n.paramReports)</title>
    <link href="~/ruoveaui/xg6rvft8p/avue/index.css" rel="stylesheet" />
    <link href="~/ruoveaui/xg6rvft8p/elementui/index.min.css" rel="stylesheet" />

</head>
<body>

    <div id="app" v-cloak>
        <avue-crud ref="crud"
                   :option="option"
                   :data="reportList"
                   :page.sync="page"
                   :table-loading="loading"
                   v-model="queryParams"
                   @@search-change="handleQuery"
                   @@search-reset="resetQuery"
                   @@size-change="handleSizeChange"
                   @@current-change="handleCurrentChange"
                   @@excel-btn="handleExport"
                   @@sort-change="handleSortChange">
            <!-- 自定义列内容显示 -->
            <template v-for="col in reportSqlColumn" :slot="col.sqlField" slot-scope="scope">
                    <!-- 字典值显示 -->
                    <span v-if="dicts[col.sqlField]" v-html="safeFormatDictLabel(col.sqlField, scope.row[col.sqlField])"></span>

                    <!-- 自定义格式化 -->
                    <span v-else-if="!isEmpty(col.formatter)" v-html="evalFun(col.formatter, col.sqlField)(scope.row, scope.row[col.sqlField])"></span>

                    <!-- 普通显示 -->
                    <span v-else>{{ scope.row[col.sqlField] }}</span>
            </template>

            <template slot="menuRight">
                <el-button icon="el-icon-download" size="mini" circle type="icon" @@click="handleExport" v-if="option.excelShowBtn"></el-button>
            </template>
        </avue-crud>
    </div>
    <script src="~/ruoveaui/xg6rvft8p/vue/vue.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/index.i18n.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/index.lang.js"></script>
    <script>
        Vue.prototype.i18n.messages.zhCN = { ...Vue.prototype.i18n.messages.zhCN, ...{"confirm_export": "是否确认导出所查找的数据项?","warning": "警告","confirm": "确定","cancel": "取消","export_canceled": "取消导出","export_success": "导出成功，文件开始下载","select_placeholder": "请选择","date_range_placeholder": "范围","input_placeholder": "请输入","start_time": "开始时间","end_time": "结束时间","to": "至","status_active": "启用","status_inactive": "禁用","yes": "是","no": "否"}};
        Vue.prototype.i18n.messages.en = { ...Vue.prototype.i18n.messages.en, ...{"confirm_export": "Confirm to export the searched items?","warning": "Warning","confirm": "Confirm","cancel": "Cancel","export_canceled": "Export canceled","export_success": "Export successful, file download started","select_placeholder": "Please select","date_range_placeholder": "range","input_placeholder": "Please enter","start_time": "Start time","end_time": "End time","to": "to","status_active": "Active","status_inactive": "Inactive","yes": "Yes","no": "No"}};
        Vue.prototype.i18n.messages.fr = { ...Vue.prototype.i18n.messages.fr, ...{"confirm_export": "Confirmer l'exportation des éléments recherchés?","warning": "Avertissement","confirm": "Confirmer","cancel": "Annuler","export_canceled": "Exportation annulée","export_success": "Exportation réussie, téléchargement du fichier commencé","select_placeholder": "Veuillez sélectionner","date_range_placeholder": "plage","input_placeholder": "Veuillez entrer","start_time": "Heure de début","end_time": "Heure de fin","to": "à","status_active": "Actif","status_inactive": "Inactif","yes": "Oui","no": "Non"}};
        Vue.prototype.i18n.messages.ja = { ...Vue.prototype.i18n.messages.ja, ...{"confirm_export": "検索したデータ項目をエクスポートしますか？","warning": "警告","confirm": "確認","cancel": "キャンセル","export_canceled": "エクスポートがキャンセルされました","export_success": "エクスポート成功、ファイルのダウンロードを開始しました","select_placeholder": "選択してください","date_range_placeholder": "範囲","input_placeholder": "入力してください","start_time": "開始時間","end_time": "終了時間","to": "から","status_active": "有効","status_inactive": "無効","yes": "はい","no": "いいえ"}};
        Vue.prototype.i18n.messages.vi = { ...Vue.prototype.i18n.messages.vi, ...{"confirm_export": "Xác nhận xuất các mục dữ liệu đã tìm kiếm?","warning": "Cảnh báo","confirm": "Xác nhận","cancel": "Hủy bỏ","export_canceled": "Đã hủy xuất","export_success": "Xuất thành công, bắt đầu tải xuống tệp","select_placeholder": "Vui lòng chọn","date_range_placeholder": "phạm vi","input_placeholder": "Vui lòng nhập","start_time": "Thời gian bắt đầu","end_time": "Thời gian kết thúc","to": "đến","status_active": "Kích hoạt","status_inactive": "Vô hiệu hóa","yes": "Có","no": "Không"}};
        Vue.prototype.i18n.messages.zhTW = { ...Vue.prototype.i18n.messages.zhTW, ...{"confirm_export": "是否確認匯出所查找的數據項?","warning": "警告","confirm": "確定","cancel": "取消","export_canceled": "取消匯出","export_success": "匯出成功，文件開始下載","select_placeholder": "請選擇","date_range_placeholder": "範圍","input_placeholder": "請輸入","start_time": "開始時間","end_time": "結束時間","to": "至","status_active": "啟用","status_inactive": "禁用","yes": "是","no": "否"}};
    </script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/index.min.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/lang/zhCN.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/lang/en.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/lang/fr.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/lang/ja.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/lang/vi.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/elementui/lang/zhTW.js"></script>
    <script>Vue.prototype.$baseURL = "@Reports?.PrefixRoute";</script>
    <script src="~/ruoveaui/xg6rvft8p/vue/axios.min.min.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/vue/vue-i18n.min.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/avue/avue.min.js"></script>
    <script src="~/ruoveaui/xg6rvft8p/avue/avue.min.option.js"></script>
    <script src="/ruoveaui/xg6rvft8p/avue/filesaver.min.js"></script>
    <script src="/ruoveaui/xg6rvft8p/avue/xlsx.full.min.js"></script>
    <script>
        new Vue({
            el: '#app',
            mixins: [curdMixin],
            data() {
                return {
                    themeV: localStorage.getItem('themeV'),
                    loading: false,
                    reportId: `@ViewBag.id`,
                    reportSqlColumn: [],
                    queryColumn: [],
                    queryParams: {},
                    dicts: {},
                    reportList: [],
                    page: {
                        pageSize: 20,
                        currentPage: 1,
                        total: 0
                    },
                    option: {
                        searchShowBtn: Permissions.avePermission(`rptquery:searchBtn`),
                        excelShowBtn: Permissions.avePermission(`rptquery:excelBtn`),
                        refreshBtn: false,
                        searchShow: false,
                        excelBtn:false,
                        menu: false,
                        addBtn: false,
                        editBtn: false,
                        delBtn: false,
                        viewBtn: false,
                        columnBtn:false,
                        column: [],
                        page: true,
                        index: false,
                        sortable: true,
                        highlightCurrentRow: true,
                        pageSizes: [10, 20, 50, 100],
                        pageSize: 20,
                        searchLabelWidth: 100,
                    }
                }
            },
            mounted() {
                this.getReportColumn();
                this.getList();
            },
            methods: {
                // 获取报表列配置
                getReportColumn() {
                    this.$http.get("/RptSql/getReportSqlInfo?id="+this.reportId).then(ret => {
                        let reportSqlColumns = ret;
                        let allColumns = [];

                        reportSqlColumns.forEach(item => {
                            
                            const column = {
                                label: item.columnName,
                                prop: item.sqlField,
                                slot: item.isList === 1,
                                width: item.width > 0 ? item.width : undefined,
                                align: item.align || 'left',
                                sortable: Boolean(item.isSortable),
                                overHidden: true,
                                search: item.isQuery === 1 && !(item.isOutput || item.isHidden),
                                display: !item.isHidden,
                                clearable: true,
                                placeholder: this.getPlaceholder(item),
                                type: this.getFieldType(item),
                                dicData: [],
                                rules: [],
                                span: this.getFieldSpan(item)
                            };

                            // 特殊处理日期范围控件
                            if (item.htmlType === 'datetime' && item.queryType === 'BETWEEN') {
                                column.searchRange = true;
                                column.type = 'daterange';
                                column.format = 'yyyy-MM-dd HH:mm:ss';
                                column.valueFormat = 'yyyy-MM-dd HH:mm:ss';
                                column.rangeSeparator = this.i18n.t('to');
                                column.startPlaceholder = this.i18n.t('start_time');
                                column.endPlaceholder = this.i18n.t('end_time');
                            }

                            // 处理字典数据
                            if (item.htmlTypeQuery !== 'tree-select' && item.dictType) {
                                if (this.validateDictFormat(item.dictType)) {
                                    let dictData = typeof item.dictType === 'string' ? JSON.parse(item.dictType) : item.dictType;
                                    dictData = this.normalizeDictData(dictData);
                                    column.dicData = dictData;
                                    this.$set(this.dicts, item.sqlField, dictData);
                                } else {
                                    getDicts(item.dictType).then(ret => {
                                        const normalizedData = this.normalizeDictData(ret.data);
                                        column.dicData = normalizedData;
                                        this.$set(this.dicts, item.sqlField, normalizedData);
                                    }).catch(error => {
                                        console.error(`获取字典 ${item.dictType} 失败:`, error);
                                    });
                                }
                            }
                            if(item.isList === 1){
                                allColumns.push(column);
                            }

                            // 初始化查询参数
                            if (column.search && !this.queryParams[item.sqlField]) {
                                if (column.type === 'daterange') {
                                    this.$set(this.queryParams, item.sqlField, []);
                                } else {
                                    this.$set(this.queryParams, item.sqlField, '');
                                }
                            }
                        });

                        this.option.column = allColumns;
                        this.reportSqlColumn = reportSqlColumns;

                    }).catch(error => {
                        console.error('获取报表列配置失败:', error);
                    });
                },

                // 获取报表数据
                getList() {
                    this.loading = true;

                    // 处理查询参数
                    const params = {
                        ...this.queryParams,
                        pageNo: this.page.currentPage,
                        pageSize: this.page.pageSize
                    };

                    // 处理日期范围参数
                    Object.keys(params).forEach(key => {
                        if (Array.isArray(params[key]) && params[key].length === 2) {
                            const startTime = params[key][0];
                            const endTime = params[key][1];

                            if (startTime && endTime) {
                                // 设置多种可能的参数名以适应不同后端接口
                                params[key] = startTime;
                                params[key + 'Begin'] = startTime;
                                params[key + 'End'] = endTime;
                                params[key + 'SecValue'] = endTime;
                            } else {
                                params[key] = null;
                                delete params[key + 'Begin'];
                                delete params[key + 'End'];
                                delete params[key + 'SecValue'];
                            }
                        }
                    });

                    this.$http.get("/RptQuery/list/"+this.reportId, {params: params}).then(ret => {
                        this.reportList = ret.rows;
                        this.page.total = ret.totalRows;
                        this.loading = false;
                    }).catch(error => {
                        console.error('获取报表数据失败:', error);
                        this.loading = false;
                    });
                },

                // 搜索
                handleQuery(params, done) {
                    this.page.currentPage = 1;

                    // 处理日期范围参数
                    const processedParams = { ...params };
                    Object.keys(processedParams).forEach(key => {
                        const columnConfig = this.option.column.find(col => col.prop === key);
                        if (columnConfig && columnConfig.type === 'daterange') {
                            console.log(`日期范围参数 ${key}:`, processedParams[key]);
                        }
                    });

                    this.queryParams = processedParams;
                    this.getList();
                    if (done) done();
                },

                // 重置搜索
                resetQuery() {
                    // 重置查询参数，保留日期范围的数组结构
                    this.option.column.forEach(col => {
                        if (col.search) {
                            if (col.type === 'daterange') {
                                this.$set(this.queryParams, col.prop, []);
                            } else {
                                this.$set(this.queryParams, col.prop, '');
                            }
                        }
                    });
                    this.page.currentPage = 1;
                    this.getList();
                },

                // 导出
                handleExport() {
                    this.$confirm(this.i18n.t('confirm_export'), this.i18n.t('warning'), {
                        confirmButtonText: this.i18n.t('confirm'),
                        cancelButtonText: this.i18n.t('cancel'),
                        type: 'warning'
                    }).then(() => {
                        const exportParams = { ...this.queryParams };

                        // 处理日期范围参数
                        Object.keys(exportParams).forEach(key => {
                            if (Array.isArray(exportParams[key]) && exportParams[key].length === 2) {
                                const startTime = exportParams[key][0];
                                const endTime = exportParams[key][1];
                                if (startTime && endTime) {
                                    exportParams[key] = startTime;
                                    exportParams[key + 'SecValue'] = endTime;
                                }
                            }
                        });
                        exportParams['name'] = "@ViewBag.name";

                        this.downloadFile("/RptQuery/export/" + this.reportId, exportParams, `${this.i18n.t('report_data')}_${new Date().getTime()}.csv`);
                    }).catch(() => {
                        this.$message.info('取消导出');
                    });
                },

                // 分页大小改变
                handleSizeChange(val) {
                    this.page.pageSize = val;
                    this.getList();
                },

                // 当前页改变
                handleCurrentChange(val) {
                    this.page.currentPage = val;
                    this.getList();
                },

                // 排序变化
                handleSortChange(column) {
                    if (column.order) {
                        const order = column.order === 'descending' ? 'desc' : 'asc';
                        this.queryParams['@@orderBy'] = `${column.prop} ${order}`;
                    } else {
                        this.queryParams['@@orderBy'] = null;
                    }
                    this.getList();
                },

                // 获取字段类型
                getFieldType(item) {
                    if (item.htmlType === 'select' && item.dictType) {
                        return 'select';
                    } else if (item.htmlType === 'datetime' && item.queryType === 'BETWEEN') {
                        return 'daterange';
                    } else if (item.htmlType === 'datetime') {
                        return 'datetime';
                    } else if (item.htmlType === 'date') {
                        return 'date';
                    }
                    return 'input';
                },

                // 获取字段占位符
                getPlaceholder(item) {
                    if (item.htmlType === 'select' && item.dictType) {
                        return `${this.i18n.t('select_placeholder')}${item.columnName}`;
                    } else if (item.htmlType === 'datetime' && item.queryType === 'BETWEEN') {
                        return `${this.i18n.t('select_placeholder')}${item.columnName}${this.i18n.t('date_range_placeholder')}`;
                    } else if (item.htmlType === 'datetime') {
                        return `${this.i18n.t('select_placeholder')}${item.columnName}`;
                    } else if (item.htmlType === 'date') {
                        return `${this.i18n.t('select_placeholder')}${item.columnName}`;
                    }
                    return `${this.i18n.t('input_placeholder')}${item.columnName}`;
                },

                // 获取字段宽度
                getFieldSpan(item) {
                    if (item.htmlType === 'datetime' && item.queryType === 'BETWEEN') {
                        return 12;
                    } else if (item.htmlType === 'datetime' || item.htmlType === 'date') {
                        return 8;
                    } else if (item.htmlType === 'select' || item.htmlType === 'tree-select') {
                        return 8;
                    }
                    return 8;
                },

                // 验证字典格式
                validateDictFormat(data) {
                    if (typeof data === 'string') {
                        try {
                            data = JSON.parse(data);
                        } catch (e) {
                            return false;
                        }
                    }
                    if (!data) { return false; }
                    if (!Array.isArray(data)) { return false; }
                    const isValid = data.every((item, index) => {
                        if (!item || typeof item !== 'object') { return false; }
                        const hasValue = item.hasOwnProperty('value') || item.hasOwnProperty('dictValue');
                        const hasLabel = item.hasOwnProperty('label') || item.hasOwnProperty('dictLabel');
                        return hasValue && hasLabel;
                    });
                    return isValid;
                },

                // 安全获取字典选项
                safeGetDictOptions(field) {
                    const dictData = this.dicts[field];
                    return Array.isArray(dictData) ? dictData : [];
                },

                // 安全格式化字典标签（带颜色）
                safeFormatDictLabel(field, value) {
                    const options = this.safeGetDictOptions(field);
                    if (!options.length || value === null || value === undefined) {
                        return value;
                    }

                    const dictItem = options.find(item => item.value == value);
                    if (!dictItem) return value;

                    const fieldName = field.toLowerCase();
                    const valueStr = String(value).toLowerCase();

                    if (fieldName.includes('status') || fieldName.includes('enable') ||
                        fieldName.includes('is') || fieldName.includes('flag')) {
                        if (value == 1 || value == '1' || value === true || valueStr === 'true' || valueStr === '是' || valueStr === 'yes') {
                            return `<span style="color: #67c23a; font-weight: bold;">${dictItem.label}</span>`;
                        } else if (value == 0 || value == '0' || value === false || valueStr === 'false' || valueStr === '否' || valueStr === 'no') {
                            return `<span style="color: #f56c6c; font-weight: bold;">${dictItem.label}</span>`;
                        }
                    }

                    return dictItem.label;
                },

                // 规范化字典数据格式
                normalizeDictData(data) {
                    if (!data || !Array.isArray(data)) return [];

                    return data.map(item => {
                        if (item.value !== undefined && item.label !== undefined) {
                            return item;
                        }
                        if (item.dictValue !== undefined && item.dictLabel !== undefined) {
                            return {
                                value: item.dictValue,
                                label: item.dictLabel
                            };
                        }
                        const keys = Object.keys(item);
                        if (keys.length >= 2) {
                            return {
                                value: item[keys[0]],
                                label: item[keys[1]]
                            };
                        }
                        return item;
                    });
                },

                // 执行格式化函数
                evalFun(js, col) {
                    try {
                        if (!js) return (row, value) => value;
                        const func = eval(js);
                        return typeof func === 'function' ? func : (row, value) => value;
                    } catch (error) {
                        console.error(`[${col}] 单元格格式化脚本异常:`, error);
                        return (row, value) => value;
                    }
                },

                // 检查是否为空
                isEmpty(value) {
                    return value === null || value === undefined || value === '';
                },

                // 通用文件下载方法
                downloadFile(url, params, fileName) {
                    const iframe = document.createElement('iframe');
                    iframe.style.display = 'none';

                    const queryString = Object.keys(params)
                        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key] || '')}`)
                        .join('&');

                    iframe.src = url + (queryString ? '?' + queryString : '');
                    document.body.appendChild(iframe);

                    const checkDownload = setInterval(() => {
                        try {
                            if (iframe.contentWindow.document.body.innerHTML.length > 0) {
                                clearInterval(checkDownload);
                                document.body.removeChild(iframe);
                                this.$message.success('导出成功，文件开始下载');
                            }
                        } catch (e) {
                        }
                    }, 1000);

                    setTimeout(() => {
                        clearInterval(checkDownload);
                        if (document.body.contains(iframe)) {
                            document.body.removeChild(iframe);
                        }
                    }, 10000);
                }
            }
        });
    </script>

</body>
</html>